<template>
  <el-card class="card-box">
    <div class="header">
      <h2>处理情况跟踪</h2>
    </div>

    <div class="content-wrapper">
      <div class="filter-area">
        <el-form inline>
          <el-form-item label="设备ID:">
            <el-select
              v-model="searchParams.serialNumber"
              filterable remote clearable reserve-keyword
              placeholder="请输入设备ID"
              :remote-method="fetchSerialSuggestions"
              :loading="loadingSerialNumbers"
            >
              <el-option
                v-for="item in serialNumberOptions"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </el-form-item>
          <!-- <el-form-item label="申请人ID:">
            <el-input-number
              v-model="searchParams.applicantId"
              placeholder="申请人ID"
              :controls="false"
              clearable
            />
          </el-form-item> -->
          <el-form-item label="状态:">
            <el-select
              v-model="searchParams.status"
              placeholder="请选择状态"
              clearable
              style="width: 200px"
            >
              <el-option label="待分配" value="待分配" />
              <el-option label="已分配" value="已分配" />
              <el-option label="维修完毕" value="维修完毕" />
              <el-option label="已完成" value="已完成" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="loadRequests">
              <el-icon><Search /></el-icon>搜索
            </el-button>
            <el-button @click="resetSearch">
              <el-icon><Refresh /></el-icon>重置
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <div class="responsive-table-container">
        <table class="custom-table">
          <thead>
            <tr>
              <th>编号</th>
              <th>设备ID</th>
              <th>申请人ID</th>
              <th>故障描述</th>
              <th>附件</th>
              <th>申请时间</th>
              <th>维修人员ID</th>
              <th>状态</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in requestList" :key="item.id">
              <td>{{ item.id }}</td>
              <td>{{ item.serialNumber }}</td>
              <td>{{ item.applicantId }}</td>
              <td class="truncate">{{ item.faultDescription }}</td>
             <td>
  <template v-if="item.faultImageUrl">
    <template v-if="isImageFile(item.faultImageUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="item.faultImageUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(item.faultImageUrl)"
          />
        </template>
        <img :src="item.faultImageUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="item.faultImageUrl"
        :download="item.faultImageUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(item.faultImageUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
              <td>{{ formatDateTime(item.requestTime) }}</td>
              <td>{{ item.assignedToId || '-' }}</td>
              <td>
                <el-tag :type="getStatusTagType(item.status)">
                  {{ item.status }}
                </el-tag>
              </td>
              <td>
                <div class="action-btns">
                  <el-button
                    type="primary"
                    size="small"
                    @click="showProcessDetail(item.id)"
                    :disabled="item.status !== '已完成'"
                  >
                    <el-icon><View /></el-icon>查看记录
                  </el-button>
                </div>
              </td>
            </tr>
            <tr v-if="requestList.length === 0">
              <td colspan="9" class="text-center py-4">
                <el-empty description="暂无维修申请" />
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.current"
          v-model:page-size="pagination.size"
          :total="pagination.total"
          :page-sizes="[5, 10, 20]"
          layout="total, sizes, prev, pager, next, jumper"
          background
          @size-change="loadRequests"
          @current-change="loadRequests"
        />
      </div>
    </div>

    <!-- 维修记录详情对话框 -->
    <el-dialog 
      v-model="detailDialog.visible" 
      :title="`维修记录详情`" 
      width="800px"
    >
      <div v-if="currentProcess" class="detail-content">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="维修单号">
            {{ currentProcess.id }}
          </el-descriptions-item>
          <el-descriptions-item label="维修人员ID">
            {{ currentProcess.repairerId }}
          </el-descriptions-item>
          <el-descriptions-item label="开始时间">
            {{ formatDateTime(currentProcess.startTime) }}
          </el-descriptions-item>
          <el-descriptions-item label="结束时间">
            {{ formatDateTime(currentProcess.endTime) }}
          </el-descriptions-item>
          <el-descriptions-item label="总费用">
            ¥{{ currentProcess.totalCost?.toFixed(2) || '0.00' }}
          </el-descriptions-item>
        </el-descriptions>

        <el-divider>
          <el-icon><Notebook /></el-icon> 维修说明
        </el-divider>
        <div class="repair-notes">{{ currentProcess.repairNotes }}</div>

        <el-divider>
          <el-icon><Folder /></el-icon> 维修凭证
        </el-divider>
        <td>
  <template v-if="currentProcess.repairFileUrl">
    <template v-if="isImageFile(currentProcess.repairFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="currentProcess.repairFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(currentProcess.repairFileUrl)"
          />
        </template>
        <img :src="currentProcess.repairFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="currentProcess.repairFileUrl"
        :download="currentProcess.repairFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(currentProcess.repairFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
        <el-divider>
          <el-icon><Box /></el-icon> 使用配件
        </el-divider>
        <table class="custom-table">
          <thead>
            <tr>
              <th>配件名称</th>
              <th>数量</th>
              <th>单价</th>
              <th>总价</th>
              <th>凭证</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in currentParts" :key="item.id">
              <td>{{ item.partName }}</td>
              <td>{{ item.quantity }}</td>
              <td>¥{{ item.unitPrice?.toFixed(2) || '0.00' }}</td>
              <td>¥{{ (item.quantity * item.unitPrice)?.toFixed(2) || '0.00' }}</td>
              <td>
  <template v-if="item.partFileUrl">
    <template v-if="isImageFile(item.partFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="item.partFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(item.partFileUrl)"
          />
        </template>
        <img :src="item.partFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="item.partFileUrl"
        :download="item.partFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(item.partFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
            </tr>
          </tbody>
        </table>
      </div>
      <div v-else class="text-center py-4">
        <el-empty description="暂无维修记录" />
      </div>
    </el-dialog>
  </el-card>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { 
  Search, Refresh, View, Notebook, Folder, Box 
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'
import { useTokenStore } from '@/stores/token'
const tokenStore = useTokenStore()

import { Download } from '@element-plus/icons-vue'; // 导入 Download 图标组件
// 类型定义
interface RepairRequest {
  id: number
  serialNumber: string
  applicantId: number
  faultDescription: string
  faultImageUrl: string
  requestTime: string
  status: string
  assignedToId: number | null
  assignTime: string | null
  updateTime: string
  deleted: number
}

interface RepairProcess {
  id: number
  repairRequestId: number
  repairerId: number
  startTime: string
  endTime: string
  repairNotes: string
  repairFileUrl: string
  totalCost: number
  createTime: string
}

interface RepairPart {
  id: number
  repairProcessId: number
  partName: string
  quantity: number
  unitPrice: number
  totalPrice: number
  partFileUrl: string
  status: string
  approvalNotes: string
  approvalTime: string
}

// 组件状态
const requestList = ref<RepairRequest[]>([])
const currentProcess = ref<RepairProcess | null>(null)
const currentParts = ref<RepairPart[]>([])

const searchParams = reactive({
  serialNumber: null as string | null,
  applicantId: tokenStore.id,
  status: null as string | null
})

const pagination = reactive({
  current: 1,
  size: 10,
  total: 0
})

const detailDialog = reactive({
  visible: false
})

const serialNumberOptions = ref<string[]>([])
const loadingSerialNumbers = ref(false)

// 生命周期钩子
onMounted(() => {
  loadRequests()
})

// 方法
const loadRequests = async () => {
  try {
    const params: {
  page: number; // pagination.current 通常是 number 类型
  size: number; // pagination.size 通常是 number 类型
  [key: string]: any; // ✨ 添加索引签名，允许通过字符串键访问，值为 any 类型
} = {
  page: pagination.current,
  size: pagination.size,
  ...searchParams, // 展开 searchParams 的所有属性
};

// 遍历 params 对象的所有键
Object.keys(params).forEach(key => {
  // `params[key]` 现在是类型安全的访问方式，不会再报错 TS7053
  // 检查值是否严格等于 null
  if (params[key] === null) {
    delete params[key]; // 如果是 null，则从 params 对象中删除该属性
  }
});

console.log(params); // 打印修改后的 params 对象


    const response = await request({
      method: 'GET',
      url: '/repair/request/list',
      params
    })
    
    requestList.value = response.data.records
    pagination.total = response.data.total
  } catch (error) {
    ElMessage.error('获取维修申请列表失败')
    console.error(error)
  }
}

const showProcessDetail = async (requestId: number) => {
  try {
    // 根据维修申请ID查询对应的维修记录
    const response = await request({
      method: 'GET',
      url: '/repair/process/list',
      params: {
        repairRequestId: requestId,
        page: 1,
        size: 1
      }
    })
    
    if (response.data.records.length > 0) {
      currentProcess.value = response.data.records[0]
      
      // 加载配件记录
      const partsResponse = await request({
        method: 'GET',
        url: '/repair/part/list',
        params: {
          page: 1,
          size: 100,
          repairProcessId: currentProcess.value!.id
        }
      })
      
      currentParts.value = partsResponse.data.records
    } else {
      currentProcess.value = null
      currentParts.value = []
    }
    
    detailDialog.visible = true
  } catch (error) {
    console.error('获取维修记录详情失败:', error)
    ElMessage.error('获取详情失败')
  }
}

const resetSearch = () => {
  searchParams.serialNumber = null
  searchParams.applicantId = tokenStore.id
  searchParams.status = null
  loadRequests()
}

const downloadFile = (url: string) => {
  if (!url) {
    ElMessage.warning('没有可下载的附件')
    return
  }
  
  const link = document.createElement('a')
  link.href = url
  link.target = '_blank'
  link.download = url.split('/').pop() || 'attachment'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const formatDateTime = (datetime: string) => {
  if (!datetime) return ''
  return new Date(datetime).toLocaleString()
}

const getStatusTagType = (status: string) => {
  switch (status) {
    case '待处理': return 'warning'
    case '已分配': return 'primary'
    case '已完成': return 'success'
    case '已取消': return 'danger'
    default: return 'info'
  }
}

// 获取设备序列号建议
const fetchSerialSuggestions = async (query: string) => {
  if (query) {
    loadingSerialNumbers.value = true
    try {
      const res = await request<string[]>({
        method: 'GET',
        url: '/device/serial/suggestions',
        params: { keyword: query }
      })
      serialNumberOptions.value = res.data
    } catch {
      ElMessage.error('获取设备序列号失败')
    } finally {
      loadingSerialNumbers.value = false
    }
  } else {
    serialNumberOptions.value = []
  }
}
const isImageFile = (url: string): boolean => {
  return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url)
}
</script>

<style lang="scss" scoped>
.card-box {
  width: 100%;
  max-width: 100%;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

.header {
  padding: 0.8rem 1.2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e6eaf0;
  background-color: #f7f9fc;
  
  h2 {
    font-weight: 600;
    font-size: 1.4rem;
    color: #333;
    user-select: none;
    margin: 0;
  }
}

.filter-area {
  padding: 0.8rem 1.2rem;
  background-color: #fafbfc;
  border-bottom: 1px solid #e6eaf0;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  overflow-x: auto;
  white-space: nowrap;
  gap: 0.8rem;

  .el-form-item {
    margin-bottom: 0 !important;
    flex-shrink: 0;
    
    label {
      font-weight: 500;
      color: #606266;
      font-size: 0.9rem;
    }
  }

  .el-button {
    height: 32px;
    font-weight: 500;
    padding: 0 12px;
    flex-shrink: 0;
  }
}

.responsive-table-container {
  overflow-x: auto;
  background: #fff;
  padding: 0.8rem;
}

.custom-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 6px;
  font-size: 0.9rem;

  thead tr {
    background-color: #f5f7fa;
    color: #606266;
    font-weight: 600;
    user-select: none;
  }

  th, td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: middle;
    white-space: nowrap;
  }

  th {
    font-size: 0.85rem;
  }

  tbody tr {
    background-color: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    transition: background-color 0.2s ease;

    &:hover {
      background-color: #f4f9ff;
    }
  }

  .truncate {
    max-width: 180px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .action-btns {
    display: flex;
    gap: 0.4rem;

    .el-button {
      padding: 0 8px;
      height: 28px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}

.no-attachment {
  color: #a9abb0;
  font-style: italic;
  user-select: none;
  font-size: 0.85rem;
}

.pagination-container {
  background-color: #fafbfc;
  padding: 0.8rem;
  border-top: 1px solid #e6eaf0;
  display: flex;
  justify-content: center;
}

.text-center {
  text-align: center;
}

.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

/* 详情对话框样式 */
.detail-content {
  .repair-notes {
    padding: 1rem;
    background-color: #f8fafc;
    border-radius: 4px;
    white-space: pre-line;
    line-height: 1.6;
  }
  
  .file-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0;
  }
  
  .no-files {
    color: #909399;
    font-style: italic;
  }
}

/* 响应式调整 */
@media (max-width: 768px) {
  .filter-area {
    flex-wrap: wrap;
    
    .el-form-item {
      width: 100%;
      margin-right: 0;
    }
  }
}
.file-preview-wrapper {
  margin-top: 8px;
  display: flex;
  align-items: center;
  position: relative;
}

.file-preview {
  position: relative;
  display: inline-block;
  cursor: pointer;
  width: 80px;
  height: 80px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  background-color: #f5f7fa;
  text-align: center;
  line-height: 80px;
  color: #606266;
  font-size: 12px;
  transition: border-color 0.3s ease;
}

.file-preview:hover {
  border-color: #409eff;
}

.preview-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.file-name {
  display: block;
  padding: 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-hover-preview {
  position: absolute;
  top: 0;
  z-index: 20;
  display: none;
  background: white;
  padding: 6px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  min-width: 120px;
  max-width: 200px;
  max-height: 200px;
  white-space: normal;
}

.left-preview {
  right: 100%; // 左侧显示
  margin-right: 10px;
}

.zoom-img {
  width: 100%;
  height: auto;
  max-height: 180px;
  object-fit: contain;
}

.zoom-text {
  color: #303133;
  font-size: 14px;
  word-break: break-all;
}

.file-preview:hover .file-hover-preview {
  display: block;
}
.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform 0.2s ease;
  margin-right: 4px;
  vertical-align: middle;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.thumbnail-download {
  display: inline-block;
  width: 0;
  height: 0;
  overflow: hidden;
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid #ddd;
}

.image-popover {
  padding: 0 !important;
  background-color: transparent !important;
  box-shadow: none !important;
  border: none !important;
}

.preview-img {
  width: 300px; // 放大图片
  height: auto;
  max-height: 400px;
  display: block;
  object-fit: contain;
  border: none;
  border-radius: 0;
  background: transparent;
}

.thumbnail-download {
  display: none; // 你也可以用按钮代替
}
</style>